"""
终端审计API视图
"""

import json
import logging
from django.http import JsonResponse
from django.core.paginator import Paginator
from django.db.models import Q, Count
from django.db import connection
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth.models import User
from .models import Host, TerminalSession, TerminalEvent, TerminalCommand

logger = logging.getLogger(__name__)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_terminal_sessions(request):
    """获取终端会话列表"""
    try:
        # 基础查询
        sessions = TerminalSession.objects.select_related('user', 'host').order_by('-start_time')
        
        # 过滤条件
        user_id = request.GET.get('user_id')
        host_id = request.GET.get('host_id')
        start_date = request.GET.get('start_date')
        end_date = request.GET.get('end_date')
        status_filter = request.GET.get('status')
        
        if user_id:
            sessions = sessions.filter(user_id=user_id)
        if host_id:
            sessions = sessions.filter(host_id=host_id)
        if start_date:
            sessions = sessions.filter(start_time__gte=start_date)
        if end_date:
            sessions = sessions.filter(start_time__lte=end_date)
        if status_filter:
            sessions = sessions.filter(status=status_filter)
            
        # 分页
        page_size = int(request.GET.get('page_size', 20))
        page_number = int(request.GET.get('page', 1))
        
        paginator = Paginator(sessions, page_size)
        page_obj = paginator.get_page(page_number)
        
        # 序列化数据
        data = []
        for session in page_obj:
            data.append({
                'id': session.id,
                'session_id': session.session_id,
                'user': session.user.username,
                'user_name': getattr(session.user, 'first_name', '') or session.user.username,
                'host': session.host.hostname,
                'host_name': session.host.hostname,
                'host_ip': session.host.public_ip,
                'start_time': session.start_time.isoformat(),
                'end_time': session.end_time.isoformat() if session.end_time else None,
                'duration': session.duration,
                'duration_display': session.duration_display,
                'command_count': session.command_count,
                'status': session.status,
                'client_ip': session.client_ip,
            })
        
        return Response({
            'sessions': data,
            'total': paginator.count,
            'pages': paginator.num_pages,
            'current_page': page_obj.number,
            'page_size': page_size,
            'has_next': page_obj.has_next(),
            'has_previous': page_obj.has_previous(),
        })
        
    except Exception as e:
        logger.error(f"获取会话列表失败: {e}")
        return Response({
            'error': f'获取会话列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_session_playback(request, session_id):
    """获取会话回放数据"""
    try:
        # 获取会话信息
        session = TerminalSession.objects.get(session_id=session_id)
        
        # 使用原生SQL优化大数据量查询
        with connection.cursor() as cursor:
            cursor.execute('''
                SELECT timestamp, event_type, data 
                FROM cmdb_terminal_event 
                WHERE session_id = ? 
                ORDER BY timestamp
            ''', [session_id])
            
            events = []
            for row in cursor.fetchall():
                events.append([
                    float(row[0]),  # timestamp
                    row[1][0],      # event_type first char ('i' or 'o')
                    row[2]          # data
                ])
                
        # 构造asciinema格式的回放数据
        playback_data = {
            'header': {
                "version": 2,
                "width": 80,
                "height": 24,
                "timestamp": session.start_time.timestamp(),
                "title": f"Session {session_id[:8]}",
                "env": {"SHELL": "/bin/bash"}
            },
            'events': events,
            'session_info': {
                'session_id': session.session_id,
                'user': session.user.username,
                'host': f"{session.host.hostname}({session.host.public_ip})",
                'start_time': session.start_time.isoformat(),
                'duration': session.duration,
                'command_count': session.command_count,
            }
        }
        
        return Response(playback_data)
        
    except TerminalSession.DoesNotExist:
        return Response({
            'error': '会话不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        logger.error(f"获取会话回放数据失败: {e}")
        return Response({
            'error': f'获取回放数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_session_commands(request, session_id):
    """获取会话命令列表"""
    try:
        # 验证会话存在
        session = TerminalSession.objects.get(session_id=session_id)
        
        # 获取命令列表
        commands = TerminalCommand.objects.filter(session_id=session_id).order_by('timestamp')
        
        # 分页
        page_size = int(request.GET.get('page_size', 50))
        page_number = int(request.GET.get('page', 1))
        
        paginator = Paginator(commands, page_size)
        page_obj = paginator.get_page(page_number)
        
        # 序列化数据
        data = []
        for cmd in page_obj:
            data.append({
                'id': cmd.id,
                'command': cmd.command,
                'timestamp': cmd.timestamp,
                'timestamp_display': f"{int(cmd.timestamp // 60)}:{int(cmd.timestamp % 60):02d}",
                'exit_code': cmd.exit_code,
                'duration': cmd.duration,
                'duration_display': cmd.duration_display,
            })
        
        return Response({
            'commands': data,
            'session_info': {
                'session_id': session.session_id,
                'user': session.user.username,
                'host': f"{session.host.hostname}({session.host.public_ip})",
                'start_time': session.start_time.isoformat(),
            },
            'total': paginator.count,
            'pages': paginator.num_pages,
            'current_page': page_obj.number,
            'page_size': page_size,
        })
        
    except TerminalSession.DoesNotExist:
        return Response({
            'error': '会话不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        logger.error(f"获取会话命令失败: {e}")
        return Response({
            'error': f'获取命令列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_audit_statistics(request):
    """获取审计统计数据"""
    try:
        # 基础统计
        total_sessions = TerminalSession.objects.count()
        active_sessions = TerminalSession.objects.filter(status='active').count()
        total_commands = TerminalCommand.objects.count()
        
        # 用户统计
        user_stats = TerminalSession.objects.values('user__username').annotate(
            session_count=Count('id')
        ).order_by('-session_count')[:10]
        
        # 主机统计
        host_stats = TerminalSession.objects.values('host__hostname', 'host__public_ip').annotate(
            session_count=Count('id')
        ).order_by('-session_count')[:10]
        
        # 最近7天的会话趋势
        from django.utils import timezone
        from datetime import timedelta
        
        end_date = timezone.now()
        start_date = end_date - timedelta(days=7)
        
        daily_stats = []
        for i in range(7):
            day = start_date + timedelta(days=i)
            day_sessions = TerminalSession.objects.filter(
                start_time__date=day.date()
            ).count()
            daily_stats.append({
                'date': day.strftime('%Y-%m-%d'),
                'sessions': day_sessions
            })
        
        return Response({
            'total_sessions': total_sessions,
            'active_sessions': active_sessions,
            'total_commands': total_commands,
            'user_stats': list(user_stats),
            'host_stats': list(host_stats),
            'daily_stats': daily_stats,
        })
        
    except Exception as e:
        logger.error(f"获取审计统计失败: {e}")
        return Response({
            'error': f'获取统计数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_users_and_hosts(request):
    """获取用户和主机列表用于过滤"""
    try:
        # 获取有会话记录的用户
        users = User.objects.filter(
            terminalsession__isnull=False
        ).distinct().values('id', 'username', 'first_name')
        
        # 获取有会话记录的主机
        hosts = Host.objects.filter(
            terminalsession__isnull=False
        ).distinct().values('id', 'hostname', 'public_ip')
        
        return Response({
            'users': list(users),
            'hosts': list(hosts),
        })
        
    except Exception as e:
        logger.error(f"获取用户主机列表失败: {e}")
        return Response({
            'error': f'获取列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
